from PIL import Image
import cv2
import os
from moviepy.editor import *

ascii_char = list(
    "$B%314567890*WM#oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:oa+>!:+. "
)


# 获取字符
def get_char(r: int, g: int, b: int, alpha=256) -> str:
    if alpha == 0:
        return ''
    length = len(ascii_char)
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
    unit = (256.0 + 1) / length
    return ascii_char[int(gray / unit)]


# 将txt转换为图片
def AsciiFile(file_num: int) -> None:
    # 这样正好使得每行120字符
    im = Image.open("temp.jpg")
    im = im.resize((720, int(im.height / im.width * 720)),
                   Image.Resampling.NEAREST)
    # gif拆分后的图像，需要转换，否则报错，由于gif分割后保存的是索引颜色
    raw_width = im.width
    raw_height = im.height
    width = int(raw_width / 6)
    height = int(raw_height / 15)
    im = im.resize((width, height), Image.Resampling.NEAREST)

    txt = ""
    for i in range(height):
        for j in range(width):
            pixel = im.getpixel((j, i))
            if (len(pixel) == 4):
                txt += get_char(pixel[0], pixel[1], pixel[2], pixel[3])
            else:
                txt += get_char(pixel[0], pixel[1], pixel[2])

    ofile = open("./cache/" + str(file_num) + ".txt", "w")
    ofile.write(txt)
    ofile.close()


# 图片转换为文字序列
def GetTxt(ifile: str) -> None:
    # 打开文件
    vc = cv2.VideoCapture(ifile)
    if (not vc.isOpened()):
        print("输入文件不存在！")
        return

    # 打开文件夹
    if (not os.path.exists('cache')):
        os.mkdir("cache")

    # 获取帧率和高度
    fps = int(round(vc.get(cv2.CAP_PROP_FPS)))
    height = int(vc.get(4) / vc.get(3) * 720) // 15
    ofile = open("./cache/basedata.txt", "w")
    ofile.write(str(fps) + '\n' + str(height) + '\n')
    ofile.close()

    # 进行码转换
    counter = int(0)
    while (True):
        corr, frame = vc.read()
        if (not corr):
            break
        counter += 1
        cv2.imwrite("temp.jpg", frame)
        AsciiFile(counter)
        os.system("del temp.jpg")


filename = input("输入视频：")

# 生成音频
video = VideoFileClip(filename)
video.audio.write_audiofile("music.mp3")

print("开始转换，时间可能有点长……")
GetTxt(filename)
print("转换完毕，请运行main.exe")
